package plus.easydo.starter.mybatis.plus.config;

import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import lombok.Data;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.schema.Column;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import plus.easydo.core.exception.ExceptionFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author laoyu
 * @version 1.0
 */
@Data
@Configuration
@ConfigurationProperties(prefix = "easydo.mybatis-plus.tenant")
public class MybatisPlusConfig {

    private static final String ALL = "*";

    private Boolean enable = false;

    private String idColumn;

    private List<String> ignoreTable = new ArrayList<>();

    private Map<String,List<String>> ignoreInsert = new HashMap<>();


    @Autowired(required = false)
    private MybatisPlusCustomService mybatisPlusCustomService;


    /**
     * 分页插件
     *
     * @return MybatisPlusInterceptor
     * @author laoyu
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //分页差插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        //开启多租户id
        if (enable){
            interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
                @Override
                public Expression getTenantId() {
                    if (Objects.isNull(mybatisPlusCustomService)) {
                        throw ExceptionFactory.baseException("Please implement mybatisPlusCustomService！！");
                    }
                    return mybatisPlusCustomService.getTenantId();
                }
                @Override
                public String getTenantIdColumn() {
                    if (Objects.nonNull(mybatisPlusCustomService)) {
                        String idColumn = mybatisPlusCustomService.getTenantIdColumn();
                        if(CharSequenceUtil.isNotBlank(idColumn)){
                            return idColumn;
                        }
                    }
                    return idColumn;
                }
                @Override
                public boolean ignoreTable(String tableName) {
                    if (Objects.nonNull(mybatisPlusCustomService)) {
                        Result result = mybatisPlusCustomService.ignoreTable(tableName);
                        if(Objects.nonNull(result)){
                            return result.getResult();
                        }
                    }
                    return ignoreTable.contains(tableName);
                }
                @Override
                public boolean ignoreInsert(List<Column> columns, String tenantIdColumn) {
                    if (Objects.nonNull(mybatisPlusCustomService)) {
                        Result result = mybatisPlusCustomService.ignoreInsert(columns, tenantIdColumn);
                        if(Objects.nonNull(result)){
                            return result.getResult();
                        }
                    }
                    String tableName = columns.get(0).getTable().getName();
                    List<String> columnNames = ignoreInsert.get(tableName);
                    if(Objects.nonNull(columnNames) && !columnNames.isEmpty()){
                        if(columnNames.contains(ALL)){
                            return true;
                        }
                        for (Column column : columns) {
                            if(columnNames.contains(column.getColumnName())){
                                return true;
                            }
                        }
                    }
                    return false;
                }
            }));
        }
        return interceptor;
    }
}
